package com.example.recommend;

import com.example.entity.*;
import com.example.mapper.*;
import com.example.utils.TimeUtils;
import com.example.utils.TokenUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class RecommendService {
    @Resource
    private CollectMapper collectMapper;
    @Resource
    private LikesMapper likesMapper;
    @Resource
    private CommentMapper commentMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private WorksMapper worksMapper;
    @Resource
    private NotebookMapper notebookMapper;

    public List<Works> recommendWork() {
        Account currentUser = TokenUtils.getCurrentUser();
        if (ObjectUtils.isEmpty(currentUser)) {
            // 没有用户登录
            return new ArrayList<>();
        }
        // 用户的哪些行为可以认为他跟文艺作品产生了关系？收藏、点赞、评论
        // 1. 获取所有的收藏信息
        List<Collect> allCollects = collectMapper.selectWorksAll();
        // 2. 获取所有的点赞信息
        List<Likes> allCarts = likesMapper.selectWorksAll();
        // 3. 获取所有的评论信息
        List<Comment> allComments = commentMapper.selectWorksAll();
        // 4. 获取所有的用户信息
        List<User> allUsers = userMapper.selectAll(null);
        // 5. 获取所有的文艺作品信息
        List<Works> allWorks = worksMapper.selectAll(null);

        // 定义一个存储每个文艺作品和每个用户关系的List
        List<RelateDTO> data = new ArrayList<>();
        // 定义一个存储最后返回给前端的文艺作品List

        // 开始计算每个文艺作品和每个用户之间的关系数据
        for (Works works : allWorks) {
            Integer worksId = works.getId();
            for (User user : allUsers) {
                Integer userId = user.getId();
                int index = 1;
                // 1. 判断该用户有没有收藏该文艺作品，收藏的权重我们给 2
                Optional<Collect> collectOptional = allCollects.stream().filter(x -> x.getFid().equals(worksId) && x.getUserId().equals(userId)).findFirst();
                if (collectOptional.isPresent()) {
                    index += 2;
                }
                // 2. 判断该用户有没有给该文艺作品点赞，点赞的权重我们给 2
                Optional<Likes> likesOptional = allCarts.stream().filter(x -> x.getFid().equals(worksId) && x.getUserId().equals(userId)).findFirst();
                if (likesOptional.isPresent()) {
                    index += 2;
                }
                // 3. 判断该用户有没有对该文艺作品评论过，评论的权重我们给 1
                Optional<Comment> commentOptional = allComments.stream().filter(x -> x.getFid().equals(worksId) && x.getUserId().equals(userId)).findFirst();
                if (commentOptional.isPresent()) {
                    index += 2;
                }
                if (index > 1) {
                    RelateDTO relateDTO = new RelateDTO(userId, worksId, index);
                    data.add(relateDTO);
                }
            }
        }

        // 数据准备结束后，就把这些数据一起喂给这个推荐算法
        List<Integer> worksIds = UserCF.recommend(currentUser.getId(), data);
        Collections.shuffle(worksIds, new Random());
        // 把文艺作品id转换成文艺作品

        //        if (CollectionUtil.isEmpty(recommendResult)) {
        //            // 随机给它推荐10个
        //            return getRandomGoods(10);
        //        }
        //        if (recommendResult.size() < 10) {
        //            int num = 10 - recommendResult.size();
        //            List<Goods> list = getRandomGoods(num);
        //            result.addAll(list);
        //        }
        List<Works>list=worksIds.stream().map(worksId -> allWorks.stream()
                        .filter(x -> x.getId().equals(worksId)).findFirst().orElse(null))
                .limit(4).collect(Collectors.toList());
        list.forEach(entity->entity.setReleaseTime(TimeUtils.TimestampToDateFormat(entity.getCreateTime())));
        return list;
    }

    public List<Notebook> recommendNotebook() {
        Account currentUser = TokenUtils.getCurrentUser();
        if (ObjectUtils.isEmpty(currentUser)) {
            // 没有用户登录
            return new ArrayList<>();
        }
        // 用户的哪些行为可以认为他跟文艺作品产生了关系？收藏、点赞、评论
        // 1. 获取所有的收藏信息
        List<Collect> allCollects = collectMapper.selectNotebookAll();
        // 2. 获取所有的点赞信息
        List<Likes> allCarts = likesMapper.selectNotebookAll();
        // 3. 获取所有的评论信息
        List<Comment> allComments = commentMapper.selectNotebookAll();
        // 4. 获取所有的用户信息
        List<User> allUsers = userMapper.selectAll(null);
        // 5. 获取所有的文艺作品信息
        List<Notebook> allNotebook = notebookMapper.selectAll(null);

        // 定义一个存储每个文艺作品和每个用户关系的List
        List<RelateDTO> data = new ArrayList<>();
        // 定义一个存储最后返回给前端的文艺作品List

        // 开始计算每个文艺作品和每个用户之间的关系数据
        for (Notebook notebooks : allNotebook) {
            Integer notebooksId = notebooks.getId();
            for (User user : allUsers) {
                Integer userId = user.getId();
                int index = 1;
                // 1. 判断该用户有没有收藏该文艺作品，收藏的权重我们给 2
                Optional<Collect> collectOptional = allCollects.stream().filter(x -> x.getFid().equals(notebooksId) && x.getUserId().equals(userId)).findFirst();
                if (collectOptional.isPresent()) {
                    index += 2;
                }
                // 2. 判断该用户有没有给该文艺作品点赞，点赞的权重我们给 2
                Optional<Likes> likesOptional = allCarts.stream().filter(x -> x.getFid().equals(notebooksId) && x.getUserId().equals(userId)).findFirst();
                if (likesOptional.isPresent()) {
                    index += 2;
                }
                // 3. 判断该用户有没有对该文艺作品评论过，评论的权重我们给 1
                Optional<Comment> commentOptional = allComments.stream().filter(x -> x.getFid().equals(notebooksId) && x.getUserId().equals(userId)).findFirst();
                if (commentOptional.isPresent()) {
                    index += 2;
                }
                if (index > 1) {
                    RelateDTO relateDTO = new RelateDTO(userId, notebooksId, index);
                    data.add(relateDTO);
                }
            }
        }

        // 数据准备结束后，就把这些数据一起喂给这个推荐算法
        List<Integer> notebooksId = UserCF.recommend(currentUser.getId(), data);
        Collections.shuffle(notebooksId, new Random());
        // 把文艺作品id转换成文艺作品

        //        if (CollectionUtil.isEmpty(recommendResult)) {
        //            // 随机给它推荐10个
        //            return getRandomGoods(10);
        //        }
        //        if (recommendResult.size() < 10) {
        //            int num = 10 - recommendResult.size();
        //            List<Goods> list = getRandomGoods(num);
        //            result.addAll(list);
        //        }
        List<Notebook>list=notebooksId.stream().map(worksId -> allNotebook.stream()
                        .filter(x -> x.getId().equals(worksId)).findFirst().orElse(null))
                .limit(4).collect(Collectors.toList());
        list.forEach(entity->entity.setReleaseTime(TimeUtils.TimestampToDateFormat(entity.getCreateTime())));
        return list;
    }

    private List<Works> getRandomWorks(int num) {
        List<Works> list = new ArrayList<>(num);
        List<Works> works = worksMapper.selectAll(null);
        for (int i = 0; i < num; i++) {
            int index = new Random().nextInt(works.size());
            list.add(works.get(index));
        }
        return list;
    }
}
